Skip to content

Simplify an opened multiple angle before judging it (#557) - #732

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
fix/multiple-angle-cancellation
Aug 5, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
fix/multiple-angle-cancellation

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Closes #557.

The reporter gives two expressions. Both are 0. The first was already handled — opening sin(2t) up is what settles it — and the second came back as a sum of five terms.

What was wrong

Opening a multiple angle is offered as a candidate rather than taken, because written out sin(4x) is longer than it started and the complexity metric should decide. That judgement is right. What was wrong is the form it was asked to judge.

The opened form was handed to the trigonometric rules only, which settles an expression that is already a single term. The reporter’s second expression is a quotient, and it cancels only once its terms are over a common denominator — and the passes that build one run earlier in the loop, while the angles are still shut. So the metric saw the opened form with none of its payoff collected, and rightly rejected it as the longer of the two.

That the cancellation is real is easy to see in isolation:

(sin(t)^6 - (2*sin(t)*cos(t))^2*sin(t)^4/4)/sin(t)^8 - 1   =>  0    // already worked
(sin(t)^6 - sin(2*t)^2*sin(t)^4/4)/sin(t)^8 - 1            =>  ...  // same number, not reduced

Same expression, and only the shut form failed.

The fix

The opened form is simplified in full before being offered — which is exactly what Expand() and Factorize() already get two lines above, and for the same reason. Expanded as well, since the cancellation here only appears once the products are multiplied out.

One candidate, not two: offering the unexpanded opening alongside it made no difference to any expression measured and doubled the added cost.

Measured

before after
reporter’s 2nd expression sum of five terms 0 provided not sin(t) = 0 (269 ms)

Multiple angles that do not cancel keep their compact form — sin(4x), cos(6x) and sin(3x) are unchanged, and sin(2x)*cos(2x) still collapses to sin(4x)/2. They cost roughly 1.2–2× what they did, in the tens of milliseconds, and only an expression that contains a multiple angle pays anything at all.

Full suite 4858 passed / 0 failed, F# 130/130, corpus 112/117 with 0 wrong, 0 error, 0 timeout and unchanged in total time.

🤖 Generated with Claude Code

The reporter's second expression is 0 and came back as a sum of five
terms. Its first was already handled -- opening sin(2t) up is what
settles it -- and the second needs the same opening to survive one step
further than it did.

Opening a multiple angle is offered as a candidate rather than taken,
because written out sin(4x) is longer than it started, and the
complexity metric decides. That judgement is right; what was wrong is
the form it was asked to judge. The opened form was handed to the
trigonometric rules only, which settles an expression that is already a
single term. This one is a quotient, and it cancels only once its terms
are over a common denominator -- and the passes that build one run
earlier in the loop, while the angles are still shut. So the metric saw
the opened form with none of its payoff collected and rightly rejected
it as the longer of the two.

It is now simplified in full first, which is what Expand and Factorize
already get two lines above, and for the same reason. Expanded as well:
the cancellation here only appears once the products are multiplied
out, so `sin(t)^6 - (2 sin(t) cos(t))^2 sin(t)^4/4` over `sin(t)^8` has
to be opened before it reads as 1.

Only one candidate, not two. Offering the unexpanded opening as well
made no difference to any expression measured and doubled the added
cost.

Measured: the reporter's second expression from a sum of five terms to
`0 provided not sin(t) = 0`, in 269 ms. Multiple angles that do not
cancel keep their compact form -- sin(4x), cos(6x) and sin(3x) are
unchanged, and sin(8x)cos(8x) still collapses to sin(16x)/2 -- and cost
roughly 1.2 to 2 times what they did, in the tens of milliseconds; only
an expression that contains a multiple angle pays anything. Full suite
4858 passed / 0 failed, F# 130/130, corpus 112/117 with 0 wrong, 0
error, 0 timeout, and unchanged in total time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet merged commit f96aa16 into master Aug 5, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the fix/multiple-angle-cancellation branch August 5, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Simplify() does not handle complex trigonometrical statements well

1 participant